package org.example.security.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.redis.service.RedisService;
import org.example.security.annotation.RequirePermission;
import org.example.security.annotation.RequireRole;
import org.example.security.utils.AuthorizeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author 小杰_cc
 * @version 1.0
 */

/**
 * 权限校验Aspect切面
 */
@Aspect
@Component
public class AuthorizeAspect {

    @Autowired
    private RedisService redisService;

    public static final String POINTCUT_SIGN = "@annotation(org.example.security.annotation.RequirePermission) || " + "@annotation(org.example.security.annotation.RequireRole)";

    @Pointcut(POINTCUT_SIGN)
    private void pointcut(){}

    // 环绕切面，添加了RequirePermission注解的进行
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 注解鉴权
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        checkMethodAnnotation(signature.getMethod());
        try {
            // 执行原有逻辑
            return joinPoint.proceed();
        }catch (Throwable e){
            throw e;
        }
    }

    // 校验逻辑
    public void checkMethodAnnotation(Method method){
        AuthorizeUtil authorizeUtil = new AuthorizeUtil(redisService);
        // 权限校验
        RequirePermission requirePermission = method.getAnnotation(RequirePermission.class);
        if (requirePermission != null){
            authorizeUtil.checkPermission(requirePermission);
        }
        // 角色校验
        RequireRole requireRole = method.getAnnotation(RequireRole.class);
        if (requireRole != null){
            authorizeUtil.checkRole(requireRole);
        }
    }
}